/*
 * Copyright 2009 Al Phillips.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package xsd4gorm.xsd.parts

import xsd4gorm.xsd.support.XSDEdible
import xsd4gorm.xsd.support.XSDEdible
import xsd4gorm.xsd.support.XSDPart
import xsd4gorm.model.Constrainable
import xsd4gorm.model.Constrainable

/**
 *
 * @author Al Phillips
 */
class Restriction extends XSDPart implements XSDEdible, Constrainable {

    public void process(def node, def type){

        XSDType xsdType = new XSDType(node.@base)
        if (xsdType.isXSDBuiltInType()){
            type.setType(xsdType.getXSDType())
        } else {
            type.setUnresolved(true)
        }

        /**
         * simpleType Facets:
         * .length
         * minLength
         * maxLength
         * .pattern
         * .enumeration
         * TODO: whiteSpace
         * maxInclusive
         * maxExclusive
         * minInclusive
         * minExclusive
         * TODO: totalDigits
         * TODO: fractionDigits
         *
         */

        //pattern
        if (hasAttribute(node.pattern.@value)){
            type.addConstraint(matches, "'${node.pattern.@value.text()}'")
        }

        // length
        if (hasAttribute(node.length.@value)){
            type.addConstraint(size, node.length.@value.text())
        }

        // minLength
        if (hasAttribute(node.minLength.@value)){
            type.addConstraint(minSize, node.minLength.@value.text())
        }

        // maxLength
        if (hasAttribute(node.maxLength.@value)){
            type.addConstraint(maxSize, node.maxLength.@value.text())
        }

        // minInclusive
        if (hasAttribute(node.minInclusive.@value)){
            type.addConstraint(minSize, node.minInclusive.@value.text())
        }

        // maxInclusive
        if (hasAttribute(node.maxInclusive.@value)){
            type.addConstraint(maxSize, node.maxInclusive.@value.text())
        }

        // minExclusive
        if (hasAttribute(node.minExclusive.@value)){
            type.addConstraint(minSize, node.minExclusive.@value.text().toInteger() + 1)
        }

        // maxExclusive
        if (hasAttribute(node.maxExclusive.@value)){
            type.addConstraint(maxSize, node.maxExclusive.@value.text().toInteger() - 1)
        }        

        // enumeration - inList
        if (hasAttribute(node.enumeration.@value)){
            def cons = []
            node.enumeration.each {enumVal ->
                cons << "'${enumVal.@value.text()}'"
            }
            type.addConstraint(inList, cons)
        }



    }

}

